package perms

import (
	"github.com/gofiber/fiber/v2"
	"sg-backend/global"
	"sg-backend/model/user"
	"sg-backend/utils"
)

type _PermsJson struct {
	Id       uint         `json:"id"`
	Title    string       `json:"title"`
	Show     bool         `json:"show"`
	Read     bool         `json:"read"`
	Add      bool         `json:"add"`
	Edit     bool         `json:"edit"`
	Del      bool         `json:"del"`
	Children []_PermsJson `json:"children"`
}

// 根据用户ID，获取用户的权限

func UserPerm(ctx *fiber.Ctx) error {

	// 获取需要验证权限的用户ID
	userId := ctx.QueryInt("uid")

	if userId == 0 {
		return nil
	}

	// 获取用户权限数据
	data, editKeys := getUserPerm(0, uint(userId))
	return ctx.JSON(fiber.Map{
		"status":  "done",
		"message": "获取成功！",
		"data":    data,
		"editKey": editKeys,
	})
}

func getUserPerm(pid uint, userId uint) ([]_PermsJson, []uint) {
	var data []_PermsJson
	var editKey []uint

	// 开始根据菜单，获取权限数据
	var menus []user.Menu
	r := global.DB.Where("pid = ?", pid).Order("order_num asc").Find(&menus)
	if r.Error != nil {
		global.BLog.Error("获取权限菜单失败！")
		return data, editKey
	}

	// 非第一次请求，需要验证权限
	// 用于给单用户设置权限
	for _, v := range menus {

		// 验证权限
		readPerm := utils.CheckPermsByTagNoPanic(v.PrivilegeName, userId, "read")
		addPerm := utils.CheckPermsByTagNoPanic(v.PrivilegeName, userId, "add")
		updatePerm := utils.CheckPermsByTagNoPanic(v.PrivilegeName, userId, "update")
		deletePerm := utils.CheckPermsByTagNoPanic(v.PrivilegeName, userId, "delete")

		// 获取下级
		subData, subKeys := getUserPerm(v.Id, userId)
		if len(subData) != 0 {

			// 有下级菜单
			data = append(data, _PermsJson{
				Id:       v.Id,
				Title:    v.Title,
				Show:     v.Show,
				Read:     readPerm,
				Add:      addPerm,
				Edit:     updatePerm,
				Del:      deletePerm,
				Children: subData,
			})

			// 合并editKey
			editKey = append(editKey, subKeys...)

		} else {

			// 无下级
			data = append(data, _PermsJson{
				Id:    v.Id,
				Title: v.Title,
				Show:  v.Show,
				Read:  readPerm,
				Add:   addPerm,
				Edit:  updatePerm,
				Del:   deletePerm,
			})

			// 添加editKey
			editKey = append(editKey, v.Id)
		}
	}
	return data, editKey
}
